package com.sheng.leetcode.year2025.month09.day29;

import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

/**
 * @author by ls
 * @date 2025/9/29
 * <p>
 * 1039. 多边形三角剖分的最低得分<p>
 * <p>
 * 你有一个凸的 n 边形，其每个顶点都有一个整数值。给定一个整数数组 values ，其中 values[i] 是第 i 个顶点的值（即 顺时针顺序 ）。<p>
 * 假设将多边形 剖分 为 n - 2 个三角形。对于每个三角形，该三角形的值是顶点标记的乘积，三角剖分的分数是进行三角剖分后所有 n - 2 个三角形的值之和。<p>
 * 返回 多边形进行三角剖分后可以得到的最低分 。<p>
 * <p>
 * 示例 1：<p>
 * 输入：values = [1,2,3]<p>
 * 输出：6<p>
 * 解释：多边形已经三角化，唯一三角形的分数为 6。<p>
 * <p>
 * 示例 2：<p>
 * 输入：values = [3,7,4,5]<p>
 * 输出：144<p>
 * 解释：有两种三角剖分，可能得分分别为：3*7*5 + 4*5*7 = 245，或 3*4*5 + 3*4*7 = 144。最低分数为 144。<p>
 * <p>
 * 示例 3：<p>
 * 输入：values = [1,3,1,4,1,5]<p>
 * 输出：13<p>
 * 解释：最低分数三角剖分的得分情况为 1*1*3 + 1*1*4 + 1*1*5 + 1*1*1 = 13。<p>
 * <p>
 * 提示：<p>
 * n == values.length<p>
 * 3 <= n <= 50<p>
 * 1 <= values[i] <= 100<p>
 */
public class LeetCode1039 {

    @Test
    public void test01() {
//        int[] values = {1, 2, 3};
//        int[] values = {3, 7, 4, 5};
//        int[] values = {1, 3, 1, 4, 1, 5};
        int[] values = {2, 1, 4, 4};
        System.out.println(new Solution().minScoreTriangulation(values));
    }
}

class Solution {
    int n;
    int[] values;
    Map<Integer, Integer> memo = new HashMap<>();

    public int minScoreTriangulation(int[] values) {
        this.n = values.length;
        this.values = values;
        return dp(0, n - 1);
    }

    public int dp(int i, int j) {
        if (i + 2 > j) {
            return 0;
        }
        if (i + 2 == j) {
            return values[i] * values[i + 1] * values[j];
        }
        int key = i * n + j;
        if (!memo.containsKey(key)) {
            int minScore = Integer.MAX_VALUE;
            for (int k = i + 1; k < j; k++) {
                minScore = Math.min(minScore, values[i] * values[k] * values[j] + dp(i, k) + dp(k, j));
            }
            memo.put(key, minScore);
        }
        return memo.get(key);
    }
}
